package com.atguigu.paymentdemo.controller;

import com.atguigu.paymentdemo.service.WxPayService;
import com.atguigu.paymentdemo.util.HttpUtils;
import com.atguigu.paymentdemo.util.WechatPay2ValidatorForRequest;
import com.atguigu.paymentdemo.vo.R;
import com.google.gson.Gson;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@CrossOrigin //跨域
@RestController
@RequestMapping("/api/wx-pay")
@Api(tags = "网站微信支付API")
@Slf4j
public class WxPayController {

    @Resource
    private WxPayService wxPayService;

    @Resource
    private Verifier getVerifier;

    @ApiOperation("调用统一下单API，生成支付二维码")
    @PostMapping("native/{productId}")
    public R nativePay(@PathVariable Long productId) throws IOException {
        log.info("发起支付请求");

        //返回支付二维码链接和R对象
        Map<String, Object> map = wxPayService.nativePay(productId);
        return R.ok().setData(map);
    }

    /**
     * 接收微信服务器的异步支付回调通知
     *
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/native/notify")
    public String nativeNotify(HttpServletRequest request, HttpServletResponse response) {
        Gson gson = new Gson();
        Map<String, Object> repMap = new HashMap<>();    //响应给微信官方的对象
        //处理通知参数
        //将请求体转为字符串参数
        String readData = HttpUtils.readData(request);
        Map<String, Object> map = gson.fromJson(readData, HashMap.class);
        try {
            log.info("支付通知的id=====> {}", map.get("id"));

            //对订单进行处理，验签
            //验签
            WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest = new WechatPay2ValidatorForRequest(getVerifier, (String) map.get("id"), readData);
            if (!wechatPay2ValidatorForRequest.validate(request)) {
                log.error("通知验签失败");


                response.setStatus(500);
                repMap.put("code", "ERROR");
                repMap.put("message", "通知验签失败");
                return gson.toJson(repMap);
            }
            log.info("验签成功");
            //订单处理：
            wxPayService.processOrder(map);

            //判断支付响应结果，修改订单状态，以及之后的逻辑
            response.setStatus(200);
            repMap.put("code", "SUCCESS");
            repMap.put("message", "成功");
            return gson.toJson(repMap);
        } catch (Exception e) {
            log.error("失败，异常为：", e);
            response.setStatus(500);
            repMap.put("code", "ERROR");
            repMap.put("message", "失败");
            return gson.toJson(repMap);
        }

    }


    /**
     * 用户手动取消订单
     *
     * @return
     */
    @PostMapping("/cancel/{orderNo}")
    public R cancelOrder(@PathVariable String orderNo) throws Exception {
        log.info("订单取消");

        wxPayService.cancelOrders(orderNo);
        return R.ok().setMessage("订单已取消");
    }


    /**
     * 查单接口，一般用于迟迟未收到微信异步支付回调通知，系统定时任务手动查询订单支付状态，实现以后逻辑
     *
     * @return
     */
    @GetMapping("/query/{orderNo}")
    public R queryOrder(@PathVariable String orderNo) throws Exception {
        log.info("查询订单");
        String result = wxPayService.queryOrderByOrderNo(orderNo);
        return R.ok().setMessage("查询成功").data("result", result);
    }


    @ApiOperation("申请退款")
    @PostMapping("/refunds/{orderNo}/{reason}")
    public R refunds(@PathVariable String orderNo, @PathVariable String reason) throws Exception {

        log.info("申请退款");
        wxPayService.refund(orderNo, reason);
        return R.ok();
    }

}
